package icu.nil.demo.shell

import com.jcraft.jsch.Channel
import com.jcraft.jsch.JSch
import java.util.*
import java.util.concurrent.Executors
import java.util.concurrent.atomic.AtomicInteger


/**
 * Create by xiangliyou on 2020/3/11 3:54 上午.
 * email: xiangliyou@aliyun.com
 * Des:
 */
class SSH {
    private val executorService = Executors.newCachedThreadPool()

    fun testConnection() {
        val jsch = JSch()
        val session = jsch.getSession("xiang", "192.168.123.19", 5022)
        session.setPassword("1213")
        session.setConfig("StrictHostKeyChecking", "no")
        session.setConfig("PreferredAuthentications", "password,gssapi-with-mic,publickey,keyboard-interactive");

        session.connect()

        val channel = session.openChannel("shell")
//
//        channel.inputStream = System.`in`
//        channel.outputStream = System.out
        channel.connect()
        shellPrint("连接成功")

        input2(channel)

//        val scanner = Scanner(System.`in`)
//        val inputStream = channel.inputStream
//        val outputStream = channel.outputStream
        try {
//            // 接收终端消息
//            executorService.submit {
//                val buffer = ByteArray(1024)
//                while (shellRunning.get()) {
//                    // 循环读取完返回的结果
//                    val result = StringBuffer()
//                    while (inputStream.available() > 0) {
//                        val i = inputStream.read(buffer)
//                        if (i < 0) {
//                            break
//                        }
//                        result.append(String(buffer, 0, i))
//                    }
//
//                    if (result.isNotEmpty()) {
//                        shellPrint(result.toString())
//                    }
//                }
//                shellPrint("exited")
//            }
//
//            // 获取控制台输入
//            var input = ""
//            while (input != "exit") {
//                if (scanner.hasNext()) {
//                    input = scanner.nextLine()
//                    channel.setCommand(input)
//                    outputStream.flush()
//                }
//            }
//            shellRunning.set(false)
//            channel.setCommand(input)
//            outputStream.flush()

            while (!channel.isClosed) {
            }
            shellPrint("exited")

            Thread.sleep(1000L)
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            session.disconnect()
            channel.disconnect()
        }
    }

    private fun shellPrint(msg: String) {
        print(msg)
    }

    private fun input2(channel: Channel) {
        val scanner = Scanner(System.`in`)
        val inputStream = channel.inputStream
        val outputStream = channel.outputStream
        // 接收终端消息
        executorService.submit {
            val buffer = ByteArray(1024)
            // 循环读取完返回的结果
            val result = StringBuffer()

            while (true) {
                Thread.sleep(10)
                while (inputStream.available() > 0) {
                    val i = inputStream.read(buffer)
                    if (i < 0) {
                        break
                    }
                    result.append(String(buffer, 0, i))
                }

                if (result.isNotEmpty()) {
                    shellPrint(result.toString())
                    result.delete(0, result.length)
                }

                // 连接断开
                if (channel.isClosed) {
                    if (inputStream.available() > 0) {
                        continue
                    }

                    println("exit-status: " + channel.exitStatus)
                    break
                }
            }

            shellPrint("exited")
        }

        outputStream.write("top\r".toByteArray())
        outputStream.flush()

        // 获取控制台输入
        var input = ""
        while (input != "exit") {
            if (scanner.hasNext()) {
                input = scanner.nextLine()
                outputStream.write("$input\r".toByteArray())
                outputStream.flush()
            }
        }

        outputStream.flush()
    }
}

fun main(args: Array<String>) {
    SSH().testConnection()
}
